package control;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import javax.ejb.EJB;
import javax.enterprise.context.SessionScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;

import dto.PercentualRequisitoDTO;

import service.RequisitoService;
import entity.CasoUso;
import entity.Requisito;
import exception.AlmiranteException;

@Named
@SessionScoped
public class ManterCasosUsoControl implements Serializable {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = -358724161221272815L;

	@EJB
	private RequisitoService service;
	
	@Inject
	private MenuControl menu;
	
	@Inject
	private CasoUso casoUso;
	
	private List<Requisito> listRequisito;
    private List<Long> requisitosSelecionados;
    
    private List<CasoUso> listCasoUso;
	
    private List<PercentualRequisitoDTO> percentual;

	private String operacao;
	private static String OP_ALTERAR = "A";
	private static String OP_INCLUIR = "I";
	
	
	public String iniciarIncluirCasoUso() {
		operacao = OP_INCLUIR;
		casoUso = new CasoUso();
		requisitosSelecionados = new ArrayList<Long>();
		
		listRequisito = service.listarRequisitosDoProjeto(menu.getIdProjetoSelecionado());
		
		
		
		return "/pages/casoUso/editar_caso_uso";
	}
	
	public String iniciarAlterarCasoUso() {
		operacao = OP_ALTERAR;
		requisitosSelecionados = new ArrayList<Long>();
		
		try {
			Iterator<Requisito> it = casoUso.getListRequisito().iterator();
			
			while (it.hasNext()) {
				Requisito req = it.next();
				
				requisitosSelecionados.add(req.getId());
			}
			
			listRequisito = service.listarRequisitosDoProjeto(menu.getIdProjetoSelecionado());
			
		} catch (Exception e) {
			FacesContext.getCurrentInstance().addMessage(null, 
					new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ao carregar caso de uso.", ""));
			
			return listarCasoUso();
		}
		
		return "/pages/casoUso/editar_caso_uso";
	}
	
	
	public String listarCasoUso() {
		operacao = null;
		
		try {
			listCasoUso = service.listarCasoUsoDoProjeto(menu.getIdProjetoSelecionado());
		} catch (Exception e) {
			FacesContext.getCurrentInstance().addMessage(null, 
					new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ao listar caso de uso.", ""));
			return "/pages/inicial";
		}
		
		
		return "/pages/casoUso/listar_caso_uso";
	}
	
	public String incluirCasoUso() {
		try {
			relacionarRequisitorSelecionados();
			
			service.incluirCasoUso(menu.getIdProjetoSelecionado(), casoUso);
			
			FacesContext.getCurrentInstance().addMessage(null, 
					new FacesMessage(FacesMessage.SEVERITY_INFO, "Caso de uso '" + casoUso.getNomeCasoUso() +"' incluído.", ""));
			
		} catch (Exception e) {
			FacesContext.getCurrentInstance().addMessage(null, 
					new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ao cadastrar caso de uso.", ""));
	
				return "/pages/casoUso/editar_caso_uso";
		}
		return listarCasoUso();
	}

	private void relacionarRequisitorSelecionados() {
		for (int i = 0; i < requisitosSelecionados.size(); i++) {
			for (int j = 0; j < listRequisito.size(); j++) {
				if (listRequisito.get(j).getId().equals(requisitosSelecionados.get(i))){
					
					if (casoUso.getListRequisito()==null){
						casoUso.setListRequisito(new HashSet<Requisito>());
					}
					
					casoUso.getListRequisito().add(listRequisito.get(j));
					
				}
			}
		}
	}
	
	public String alterarCasoUso() {
		try {
			relacionarRequisitorSelecionados();
			
			retirarRequisitosAlterados();
			
			service.alterarCasoUso(casoUso);
			
			FacesContext.getCurrentInstance().addMessage(null, 
					new FacesMessage(FacesMessage.SEVERITY_INFO, "Caso de uso '" + casoUso.getNomeCasoUso() +"' incluído.", ""));
			
			
		} catch (Exception e) {

			FacesContext.getCurrentInstance().addMessage(null, 
					new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ao alterar caso de uso", ""));
			
			e.printStackTrace();
			
			return "/pages/casoUso/editar_caso_uso";
		}
	
		return listarCasoUso();
	}

	private void retirarRequisitosAlterados() {
		Iterator<Requisito> it = casoUso.getListRequisito().iterator();
			List<Requisito> tempReq = new ArrayList<Requisito>();
			while (it.hasNext()) {
				Requisito req = it.next();
				boolean retira = true;
				for (int i = 0; i < requisitosSelecionados.size(); i++) {
					if (requisitosSelecionados.get(i).equals(req.getId()) ){
						retira = false;
					}
				}
				if (retira){
					tempReq.add(req);
				}
			}
			
			casoUso.getListRequisito().removeAll(tempReq);
	}
	
	public String excluirCasoUso(){
		try {
			service.excluirCasoUso(casoUso);
			FacesContext.getCurrentInstance().addMessage(null, 
					new FacesMessage(FacesMessage.SEVERITY_INFO, "Sucesso ao excluir caso de uso.", ""));
		} 
		catch(AlmiranteException e){
			FacesContext.getCurrentInstance().addMessage(null, 
					new FacesMessage(FacesMessage.SEVERITY_ERROR, e.getMessage(), ""));
		}
		catch (Exception e) {
			FacesContext.getCurrentInstance().addMessage(null, 
					new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ao excluir caso de uso.", ""));
			e.printStackTrace();
			
		}
		return listarCasoUso();
	}
	
	public String obterPercentagemCasoUso(){
		
		try {
			percentual = service.obterPercentagemCasoUso(casoUso);
			
		} catch (Exception e) {
			e.printStackTrace();
			FacesContext.getCurrentInstance().addMessage(null, 
					new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ao obter percentagem dos casos uso.", ""));
		}
		return "/pages/casoUso/listar_percentual_casouso_concluido";
	}
	
	
	
	public boolean getExibirAlterar() {
		return OP_ALTERAR.equals(operacao);
	}
	
	public boolean getExibirIncluir() {
		return OP_INCLUIR.equals(operacao);
	}


	public MenuControl getMenu() {
		return menu;
	}


	public void setMenu(MenuControl menu) {
		this.menu = menu;
	}


	public CasoUso getCasoUso() {
		return casoUso;
	}


	public void setCasoUso(CasoUso casoUso) {
		this.casoUso = casoUso;
	}


	public String getOperacao() {
		return operacao;
	}


	public void setOperacao(String operacao) {
		this.operacao = operacao;
	}


	public List<Requisito> getListRequisito() {
		return listRequisito;
	}


	public void setListRequisito(List<Requisito> requisito) {
		this.listRequisito = requisito;
	}


	public List<Long> getRequisitosSelecionados() {
		return requisitosSelecionados;
	}


	public void setRequisitosSelecionados(List<Long> requisitosSelecionados) {
		this.requisitosSelecionados = requisitosSelecionados;
	}

	public List<CasoUso> getListCasoUso() {
		return listCasoUso;
	}

	public void setListCasoUso(List<CasoUso> listCasoUso) {
		this.listCasoUso = listCasoUso;
	}

	public List<PercentualRequisitoDTO> getPercentual() {
		return percentual;
	}

	public void setPercentual(List<PercentualRequisitoDTO> percentual) {
		this.percentual = percentual;
	}

}
